package com.ruoyi.web.service.device.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.constant.UserDefaultConstants;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.web.domain.device.DeviceInfo;
import com.ruoyi.web.domain.device.DeviceNumber;
import com.ruoyi.web.domain.function.FunctionConfig;
import com.ruoyi.web.mapper.device.DeviceInfoMapper;
import com.ruoyi.web.pojo.request.device.DeviceInfoRequest;
import com.ruoyi.web.service.function.FunctionConfigService;
import com.ruoyi.web.utils.v2.V2DeviceInfo;
import com.ruoyi.web.service.device.DeviceInfoService;
import com.ruoyi.web.utils.v2.V2RremoteCall;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 设备管理 服务实现类
 * @author fwx
 * @date 2024-01-08 16:03:56
 */
@Service
@DataSource(value = DataSourceType.MASTER)
public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceInfo> implements DeviceInfoService {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private FunctionConfigService functionConfigService;

    /**
    * 新增设备管理
    */
    @Override
    public void insert(DeviceInfo info){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());

        if(loginUser == null){
            throw new RuntimeException("用户未登录");
        }

        info.setUserId(loginUser.getUserId());
        info.setUsername(loginUser.getUsername());
        info.setBindTime(LocalDateTime.now());
        super.save(info);
    }

    /**
    * 修改设备管理
    */
    @Override
    public void update(DeviceInfo DeviceInfo){
        super.updateById(DeviceInfo);
    }

    /**
    * 删除设备管理
    */
    @Override
    public void delete(String id){
        super.removeById(id);
    }

    @Override
    public List<DeviceInfo> getByUser(){
        return this.getByUser((String) null);
    }

    @Override
    public List<String> getIdsByUser(String deviceType){
        List<DeviceInfo> list = this.getByUser(deviceType);

        if(CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }

        List<String> ids = list.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList());
        return ids;
    }

    @Override
    public List<DeviceInfo> getByUser(String deviceType){
        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();

        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());

        //用户id
        if(loginUser == null){
            return new ArrayList<>();
        }

        List<SysRole> roles = loginUser.getUser().getRoles();
        //管理员角色查询全部
        if(!SysRole.checkRole(roles, UserDefaultConstants.PARK_MANAGE_ROLE_KEY)){
            query.lambda().eq(DeviceInfo::getUserId,loginUser.getUserId());
        }

        if(deviceType != null){
            query.lambda().eq(DeviceInfo::getDeviceType,deviceType);
        }

        List<DeviceInfo> list = super.list(query);

        return list;
    }

    @Override
    public List<DeviceInfo> getByUser(DeviceInfoRequest request){

        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());

        //用户id
        if(loginUser == null){
            return new ArrayList<>();
        }
        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();

        List<SysRole> roles = loginUser.getUser().getRoles();
        //管理员角色查询全部
        if(!SysRole.checkRole(roles, UserDefaultConstants.PARK_MANAGE_ROLE_KEY)){
            query.lambda().eq(DeviceInfo::getUserId,loginUser.getUserId());
        }

        request.bulidWrapper(query);

        List<DeviceInfo> list = super.list(query);

        return list;
    }


    /**
    *  分页查询设备管理
    */
    @Override
    public IPage<DeviceInfo> queryPage(DeviceInfoRequest request){

        //01 查询用户下的设备
        List<DeviceInfo> deviceInfos = this.getByUser();

        //02 批量同步设备数据
        Map<String, V2DeviceInfo> v2Map = this.updateBatchSync(deviceInfos);

        //03 分页查询设备
        IPage<DeviceInfo> page = new Page<>(request.getPageNum(),request.getPageSize());

        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();

        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());

        //用户id
        if(loginUser == null){
            return page;
        }

        List<SysRole> roles = loginUser.getUser().getRoles();
        //管理员角色查询全部
        if(!SysRole.checkRole(roles, UserDefaultConstants.PARK_MANAGE_ROLE_KEY)){
            query.lambda().eq(DeviceInfo::getUserId,loginUser.getUserId());
        }

        //构造查询条件
        request.bulidWrapper(query);
        super.page(page,query); //分页查询

        if(page.getRecords().size() == 0){
            return page;
        }

        //向绿色云农查询设备信息
        for (DeviceInfo record : page.getRecords()) {
            record.buildOther(v2Map.get(record.getDeviceId()));
        }

        return page;
    }

    /**
     * @desc  批量同步设备数据
     * @author fwx 2024/2/6 15:16
     **/
    private Map<String, V2DeviceInfo> updateBatchSync(List<DeviceInfo> deviceInfos){

        if(deviceInfos.isEmpty()){
            return new HashMap<>();
        }

        List<V2DeviceInfo> v2Devices = V2RremoteCall.getByIds(deviceInfos);
        Map<String, V2DeviceInfo> v2Map = v2Devices.stream().collect(Collectors.toMap(V2DeviceInfo::getId, Function.identity()));

        //02 同步设备接口
        for (DeviceInfo record : deviceInfos) {
            record.buildOther(v2Map.get(record.getDeviceId()));
        }

        updateBatchById(deviceInfos); //批量修改
        return v2Map;
    }


    @Override
    public List<DeviceInfo> getByDeviceType(String deviceType){
        List<DeviceInfo> list = this.getByUser(deviceType);
        return list;
    }

    @Override
    public List<DeviceInfo> getAllDeviceByType(String deviceType){
        DeviceInfoRequest request = new DeviceInfoRequest();
        request.setDeviceType(deviceType);
        return this.queryAll(request);
    }

    /**
    * 查询所有设备管理
    */
    @Override
    public List<DeviceInfo> queryAll(DeviceInfoRequest request){
        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();
        //构造查询条件
        request.bulidWrapper(query);
        List<DeviceInfo> deviceInfos = super.list(query);

        //同步数据
        this.updateBatchSync(deviceInfos);

        return deviceInfos;
    }

    @Override
    public DeviceInfo getByDeviceId(String deviceId){
        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();
        query.lambda().eq(DeviceInfo::getDeviceId,deviceId);
        DeviceInfo one = super.getOne(query, false);
        return one;
    }

    @Override
    public List<DeviceInfo> getByDeviceId(List<String> deviceIds){
        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();
        query.lambda().in(DeviceInfo::getDeviceId,deviceIds);
        List<DeviceInfo> list = super.list(query);
        return list;
    }

    @Override
    public List<DeviceInfo> getByProductId(List<Long> productIds){
        if(productIds.isEmpty()){
            return new ArrayList<>();
        }

        QueryWrapper<DeviceInfo> query  = new QueryWrapper<>();
        query.lambda().in(DeviceInfo::getProductId,productIds);
        List<DeviceInfo> list = super.list(query);
        return list;
    }

    @Override
    public void bindDevice(String no, Integer type){

        String deviceId = no;
        //根据二维码编号获取设备编号
        if(type == 1){
            deviceId = V2RremoteCall.getDeviceId(no);
        }

        //判断设备是否绑定
        DeviceInfo check = this.getByDeviceId(deviceId);
        if(check != null){
            throw new RuntimeException("该设备已经绑定");
        }

        List<V2DeviceInfo> v2Devices = V2RremoteCall.getByIds(deviceId);

        if(v2Devices.size() == 0){
            return;
        }

        DeviceInfo addDevice = new DeviceInfo(v2Devices.get(0).getId(),v2Devices.get(0).getTypeCode());
        addDevice.setProductId(v2Devices.get(0).getProductId());
        this.insert(addDevice);
    }

    @Override
    public List<DeviceInfo> getDeviceByCode(String code){

        FunctionConfig function = functionConfigService.getUseConfigByCode(code);

        String pids = Optional.ofNullable(function).map(FunctionConfig::getValue1).orElse(null);

        if(StringUtils.isBlank(pids)){
            return new ArrayList<>();
        }

        DeviceInfoRequest request = new DeviceInfoRequest();
        request.setProductId(pids);
        List<DeviceInfo> list = this.getByUser(request);

        return list;
    }

    @Override
    public DeviceNumber getDeviceNumber(){
        List<DeviceInfo> userList = this.getByUser();
        Map<String, Long> devcieMap = userList.stream().collect(Collectors.groupingBy(DeviceInfo::getDeviceType, Collectors.counting()));
        DeviceNumber result = new DeviceNumber(devcieMap);
        return result;
    }


    @Override
    public List<String> getDeviceNoByCode(String code){
        List<DeviceInfo> infos = getDeviceByCode(code);
        if(CollUtil.isEmpty(infos)){
            return new ArrayList<>();
        }
        List<String> collect = infos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList());

        return collect;
    }

    @Override
    public V2DeviceInfo getV2Device(String no, Integer type){

        String deviceId = no;
        //根据二维码编号获取设备编号
        if(type == 1){
            deviceId = V2RremoteCall.getDeviceId(no);
        }

        List<V2DeviceInfo> v2Devices = V2RremoteCall.getByIds(deviceId);

        if(v2Devices.size() == 0){
            return new V2DeviceInfo();
        }

        return v2Devices.get(0);
    }


    /**
    * 根据id查询设备管理
    */
    @Override
    public DeviceInfo findById(String id){
        DeviceInfo res = super.getById(id);
        return res;
    }

}
